<!--
 * @Descripttion: 
 * @version: 
 * @Author: wtzhang
 * @Date: 2021-07-20 17:02:09
 * @LastEditors: wtzhang
 * @LastEditTime: 2021-07-21 14:20:13
-->
<template>
  <div class="toRefs">
    <h3 style="text-align: center">toRefs</h3>
    <hr />
    <br />
    <p>
      toRefs: <br />将响应式对象中所有属性包装为ref对象,
      并返回包含这些ref对象的普通对象 应用: 当从合成函数返回响应式对象时，toRefs
      非常有用，
      这样消费组件就可以在不丢失响应式的情况下对返回的对象进行分解使用。
    </p>
    <p>ref 与 toRefs的区别:</p>
    <h4>原始数据：let obj = {name:'jack'};</h4>
    <p>需求1：将obj对象中的name变成响应式数据，而不是对象obj</p><br>
    <button @click="myFn">ref测试打印</button><br><br>
    原始数据obj: {{obj}}<br>
    state1: {{state1}}
    <hr>
    <button @click="myFn2">toRef测试打印</button><br><br>
    原始数据obj: {{obj}}<br>
    state2: {{state2}}
    <hr>
    <button @click="myFn3">toRefs测试打印</button><br><br>
    原始数据obj: {{obj}}<br>
    state3: {{state3}}
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, toRef, toRefs } from "vue";
export default defineComponent({
  name: "toRefs",
  setup() {
    /*
      toRefs:
        将响应式对象中所有属性包装为ref对象, 并返回包含这些ref对象的普通对象
        应用: 当从合成函数返回响应式对象时，toRefs 非常有用，
        这样消费组件就可以在不丢失响应式的情况下对返回的对象进行分解使用
    */

    // ref 与 toRefs的区别
    // 需求1：将obj对象中的name变成响应式数据，而不是对象obj
    let obj = { name: "jack", age: 18 };
    /**
     * ref(obj.name) ---相当于----> ref(jack)
     * ref(obj.name) ---相当于----> reactive({value: jack}) // reactive({key: 值})
     */
    let state1 = ref(obj.name) // 使用ref将name变成了响应式数据
    // console.warn(state1);
    let state2 = toRef(obj, 'name')
    // console.warn(state2);
    let state3 = toRefs(obj)
    console.warn(state3);
    
    
    
    function myFn(){
      console.error('ref测试执行。。。');
      // 修改响应式数据
      state1.value = 'rose'
      console.log(obj);
      console.log(state1);
      /**
       * 结论：
       * 如果利用ref将某一个对象中的属性变成响应式数据
       * 我们修改响应式数的数据是 不会影响 原数据的，但会影响界面UI显示， ref 相当于复制
       */
    }
    function myFn2() {
      console.error('toRef测试执行。。。');
      // 修改响应式数据
      state2.value = 'rose'
      console.log(obj);
      console.log(state2);
      /**
       * 结论：
       * 如果利用 toRef将某一个对象中的属性变成响应式数据
       * 我们修改响应式数的数据是 会影响 原数据的，但是界面UI不会影响，toRef 相当于 引用
       */
    }
    function myFn3() {
      console.error('toRefs测试执行。。。');
      // 修改响应式数据
      state3.name.value = 'rose'
      state3.age.value = 16
      console.log(obj);
      console.log(state3);
      /**
       * 结论：
       * 如果利用 toRefs将某一个对象中的所有属性变成响应式数据
       * 我们修改响应式数的数据是 会影响 原数据的，但是界面UI不会影响，toRefs 相当于 引用
       */
    }
    return {
      obj,
      state1,
      state2,
      state3,
      myFn,
      myFn2,
      myFn3
    };
  },
});
</script>

<style>
.toRefs {
  padding: 16px;
}
</style>